package cn.da.shuai.cool.system.api.controller;

import cn.da.shuai.cool.common.view.BasicView;
import cn.da.shuai.cool.common.entity.R;
import cn.da.shuai.cool.common.web.util.IpUtil;
import cn.da.shuai.cool.security.api.model.LoginRecord;
import cn.da.shuai.cool.security.api.util.JwtUtil;
import cn.da.shuai.cool.system.model.entity.dept.DeptUserDto;
import cn.da.shuai.cool.system.model.entity.dept.UpdateDeptUserVo;
import cn.da.shuai.cool.system.model.entity.user.*;
import cn.da.shuai.cool.system.model.enums.user.UserStatusType;
import cn.da.shuai.cool.system.service.service.ICoolUserService;
import cn.da.shuai.cool.system.service.util.UserUtil;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Tag(name = "用户管理")
@RestController
@RequestMapping("/system/user")
public class CoolUserController {

    @Resource
    private ICoolUserService coolUserService;

    @Autowired
    private AuthenticationManager authenticationManager;


    @Operation(summary = "用户登陆")
    @PostMapping("/login")
    public R<Map<String,String>> login(@RequestBody LoginRecord vo, HttpServletRequest request) {
        Authentication auth = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(vo.username(), vo.password())
        );
        SecurityContextHolder.getContext().setAuthentication(auth);
        String token = JwtUtil.generateToken(vo.username());
        coolUserService.updateIp(UserUtil.getUserId(), IpUtil.getClientIpAddress(request));
        return R.ok(Map.of("token", token));
    }

    @Operation(summary = "新增用户")
    @PostMapping("/add")
    public R<Boolean> add(@RequestBody @Validated SaveUserVo vo) {
        return R.ok(coolUserService.add(vo));
    }

    @Operation(summary = "重置密码")
    @PutMapping("/reset/password/{id}")
    public R<Boolean> resetPassword(@PathVariable("id") Integer id) {
        return R.ok(coolUserService.resetPassword(id));
    }

    @Operation(summary = "修改密码")
    @PutMapping("/modify/password")
    public R<Boolean> modifyPassword(@RequestBody @Validated ModifyPasswordVo vo) {
        return R.ok(coolUserService.modifyPassword(vo));
    }

    @Operation(summary = "修改用户状态")
    @PutMapping("/change/status/{id}/{status}")
    public R<Boolean> changeStatus(@PathVariable("id") Integer id, @PathVariable("status") UserStatusType status) {
        return R.ok(coolUserService.changeStatus(id, status));
    }

    @Operation(summary = "更新用户信息")
    @PutMapping("/update")
    public R<Boolean> update(@RequestBody @Validated SaveUserVo vo) {
        return R.ok(coolUserService.update(vo));
    }

    @JsonView(UserDto.Detail.class)
    @Operation(summary = "获取用户详情(包括部门)")
    @GetMapping("/detail/{id}")
    public R<UserDto> detail(@PathVariable Integer id) {
        return R.ok(coolUserService.getDetails(id));
    }

    @JsonView(BasicView.class)
    @Operation(summary = "根据id获取用户信息(不包括部门)")
    @GetMapping("/{id}")
    public R<UserDto> getById(@PathVariable Integer id) {
        return R.ok(coolUserService.one(id, UserDto.class));
    }

    @Operation(summary = "更新用户部门")
    @PutMapping("/update/dept/user")
    public R<Boolean> updateDeptUser(@RequestBody @Validated UpdateDeptUserVo vo) {
        return R.ok(coolUserService.updateDeptUser(vo));
    }

    @Operation(summary = "获取用户部门列表")
    @GetMapping("/dept/user/{userId}")
    public R<List<DeptUserDto>> getDeptUserList(@PathVariable Integer userId) {
        return R.ok(coolUserService.getDeptUserList(userId));
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/delete/{id}")
    public R<Boolean> delete(@PathVariable Integer id) {
        return R.ok(coolUserService.removeById(id));
    }

    @PostMapping("/list")
    @Operation(summary = "获取用户列表")
    public R<List<UserListDto>> getUserList(@RequestBody @Validated SearchUserVo vo) {
        return R.ok(coolUserService.getUserList(vo));
    }
}
